/* eslint-disable @typescript-eslint/triple-slash-reference */
/* eslint-disable @typescript-eslint/ban-ts-comment */
/// <reference path='../node_modules/@i3yun/viewer/dist/dts/Sippreep.d.ts'/>

import { VisibilityManager } from "./VisibilityManager";

/**
 * 重新赋值model的visibilityManager，以便在getState和restoreState时候记录和恢复数据
 *
 */
export class NodeOffHackExtension extends Sippreep.Viewing.Extension {
    readonly version = "2022.05.13 - fix_model_urn";
    /**
     * 在viewerState中占用的字段
     */
    private readonly stateName = "nodeOff";

    private onModelLoadedBind = ((ev: { model: Sippreep.Viewing.Model }) => {
        ev.model.visibilityManager = new VisibilityManager(this.viewer.impl, ev.model);
    }).bind(this);

    load(): boolean {
        // 用于插件先加载，模型后加载
        this.viewer.addEventListener(Sippreep.Viewing.MODEL_ADDED_EVENT, this.onModelLoadedBind);
        // 用于模型先加载，插件后加载
        for (const m of this.viewer.getAllModels()) {
            m.visibilityManager = new VisibilityManager(this.viewer.impl, m);
        }
        return true;
    }
    unload(): boolean {
        this.viewer.removeEventListener(Sippreep.Viewing.MODEL_ADDED_EVENT, this.onModelLoadedBind);
        for (const m of this.viewer.getAllModels()) {
            // @ts-ignore
            m.visibilityManager = new Sippreep.Viewing.Private.VisibilityManager(this.viewer.impl, m);
        }
        return true;
    }
    /**
     * 在viewer.getState()时自动运行
     *
     * stateName:[
     * {urn:"", offNodes:"", },
     * {urn:"", offNodes:"", },
     * ]
     * @param viewerState
     * @returns
     */
    getState(viewerState: Record<string, any>) {
        viewerState[this.stateName] = [] as Record<string, any>[];
        for (const m of this.viewer.getAllModels()) {
            // @ts-ignore
            const tempNodes = m.visibilityManager.getOffNodes();
            if (tempNodes.length < 1) {
                continue;
            }
            const mInfo: Record<string, any> = {
                // urn: m.getData().urn,
                //@ts-ignore
                seedUrn: m.getSeedUrn(),
                offNodes: tempNodes
            };
            viewerState[this.stateName].push(mInfo);
        }
        return viewerState;
    }
    /**
     * 在viewer.restoreState()时自动运行
     * @param viewerState
     * @param immediate
     * @returns
     */
    restoreState(viewerState: Record<string, any>, immediate: boolean) {
        // performance.mark("restoreState-start");
        // 所有模型均恢复关闭（全部打开）
        for (const m of this.viewer.getAllModels()) {
            // @ts-ignore
            m.visibilityManager.resetNodeOff();
        }
        // performance.mark("restoreState-reset");
        // console.log(performance.measure("1", "restoreState-start", "restoreState-reset"));

        // 注意将恢复放在此判断之前
        if (!viewerState[this.stateName] || !viewerState[this.stateName].length) {
            return true;
        }
        for (const info of viewerState[this.stateName]) {
            // performance.mark("for-start");
            // @ts-ignore
            const model: Sippreep.Viewing.Model = this.viewer.impl.findModel((m: Sippreep.Viewing.Model) => {
                // return m.getData().urn == info.urn;
                //@ts-ignore
                return m.getSeedUrn() == info.seedUrn;
            }, false);
            if (model) {
                model.visibilityManager.setNodeOff(info.offNodes, true);
            }
            // performance.mark("for-end");
            // console.log(info);
            // console.log(performance.measure("2", "for-start", "for-end").duration);

        }
        return true;
    }

}
